<?php

/**
 * Menashop
 *
 * LICENSE
 *
 * This source file is subject to the license that is bundled
 * with this project in the file LICENSE.txt
 *
 * @category   Menashop
 * @package    Menashop_Content
 * @subpackage Product
 * @copyright  Copyright (c) 2011 Menashop UA Inc. (http://www.menashop.com.ua)
 * @license    LICENSE.txt
 * @version    1.0.0
 * @since      File available since Release 1.0.0
 */

/**
 * The SAX handler for product
 * 
 * @category   Menashop
 * @package    Menashop_Content
 * @subpackage Product
 * @copyright  Copyright (c) 2011 Menashop UA Inc. (http://www.menashop.com.ua)
 * @license    LICENSE.txt
 */
class Menashop_Content_Product
{

    /**
     * The data model for product
     * @var Admin_Model_Product 
     */
    protected $_productModel = null;

    /**
     * The data model for product translation
     * @var Admin_Model_ProductTranslation
     */
    protected $_productTranslationModel = null;

    /**
     * The data model for product feature
     * @var Admin_Model_ProductFeature
     */
    protected $_productFeatureModel = null;

    /**
     * The data model for product feature tranlsation
     * @var Admin_Model_ProductFeatureTranslation
     */
    protected $_productFeatureTranslationModel = null;

    /**
     * The data model for for product picture
     * @var Admin_Model_ProductPicture
     */
    protected $_productPictureModel = null;

    /**
     * The data model for manufacturer
     * @var Admin_Model_Manufacturer
     */
    protected $_manufacturerModel = null;

    /**
     * The data model for category
     * @var Admin_Model_Category
     */
    protected $_categoryModel = null;

    /**
     * The data model for category feature
     * @var Admin_Model_CategoryFeature
     */
    protected $_categoryFeatureModel = null;

    /**
     * The product
     * @var Admin_Model_Product
     */
    protected $_product = null;

    /**
     * The product translation
     * @var Admin_Model_ProductTranslation
     */
    protected $_productTranslation = null;

    /**
     * The Content product ID
     * @var integer
     */
    protected $_contentProductId = null;

    /**
     * The product ID
     * @var integer 
     */
    protected $_productId = null;

    /**
     * The language ID 
     * @var type 
     */
    protected $_languageId = null;

    /**
     * Product features
     * @var array 
     */
    protected $_productFeatures = array();

    /**
     * Product pictures
     * @var array 
     */
    protected $_productPictures = array();

    /**
     * The flag for a tag 'Product'
     * @var integer
     */
    protected $_inProduct = 0;

    /**
     * The flag for a tag 'ShortSummaryDescription'
     * @var integer 
     */
    protected $_inShortSummaryDescription = 0;

    /**
     * The flag for a tag 'LongSummaryDescription'
     * @var integer 
     */
    protected $_inLongSummaryDescription = 0;

    /**
     * The counter for product features
     * @var integer 
     */
    protected $_totalProductFeatures = 0;

    /**
     * The counter for inserted product features
     * @var integer 
     */
    protected $_totalProductFeaturesInserted = 0;

    /**
     * The counter for updated product features
     * @var integer 
     */
    protected $_totalProductFeaturesUpdated = 0;

    /**
     * The counter for product pictures
     * @var integer 
     */
    protected $_totalProductPictures = 0;

    /**
     * The counter for inserted product pictures
     * @var integer 
     */
    protected $_totalProductPicturesInserted = 0;

    /**
     * The counter for updated product pictures
     * @var integer 
     */
    protected $_totalProductPicturesUpdated = 0;

    /**
     * The config
     * @var Zend_Config
     */
    protected $_config = null;

    /**
     * The downloader for files
     * @var Menashop_Downloader
     */
    protected $_downloader = null;

    /**
     * Local images path
     * @var string
     */
    protected $_localImagesPath = null;

    /**
     * Local images URL
     * @var string
     */
    protected $_localImagesUrl = null;

    /**
     * Base content URL
     * @var string
     */
    protected $_baseContentUrl = null;

    /**
     * Initialize the SAX handler for product
     * @param integer $contentProductId
     * @param integer $languageId 
     * @param Zend_Config $config
     * @param Menashop_Downloader $downloader
     */
    public function __construct($contentProductId, $languageId, $config, $downloader)
    {
        $this->_product = array();
        $this->_productTranslation = array();
        $this->_productModel = new Admin_Model_Product();
        $this->_productTranslationModel = new Admin_Model_ProductTranslation();
        $this->_productFeatureModel = new Admin_Model_ProductFeature();
        $this->_productFeatureTranslationModel = new Admin_Model_ProductFeatureTranslation();
        $this->_productPictureModel = new Admin_Model_ProductPicture();
        $this->_manufacturerModel = new Admin_Model_Manufacturer();
        $this->_categoryModel = new Admin_Model_Category();
        $this->_categoryFeatureModel = new Admin_Model_CategoryFeature();
        $this->_contentProductId = $contentProductId;
        $this->_languageId = $languageId;
        $this->_config = $config;
        $this->_downloader = $downloader;
        $this->_localImagesPath = $this->_config->localImagesPath;
        $this->_localImagesUrl = $this->_config->localImagesUrl;
        $this->_baseContentUrl = $this->_config->baseUrl;
    }

    public function _saveProductImages()
    {
        // Save product high pic
        $highPicUrl = $this->_product['high_pic_url'];
        if ($highPicUrl) {
            $localPath = $this->_localImagesPath . substr($highPicUrl, strpos($highPicUrl, $this->_baseContentUrl) + strlen($this->_baseContentUrl));
            $localUrl = $this->_localImagesUrl . substr($highPicUrl, strpos($highPicUrl, $this->_baseContentUrl) + strlen($this->_baseContentUrl));

            // Check directory for local path
            $parentPath = dirname($localPath);
            if (!file_exists($parentPath)) {
                mkdir($parentPath, 0775, true);
            }

            if (!file_exists($localPath)) {
                $this->_downloader->downloadFile($highPicUrl, $localPath);
            }
            $this->_product['high_pic_url'] = $localUrl;
        }

        // Save product low pic
        $lowPicUrl = $this->_product['low_pic_url'];
        if ($lowPicUrl) {
            $localPath = $this->_localImagesPath . substr($lowPicUrl, strpos($lowPicUrl, $this->_baseContentUrl) + strlen($this->_baseContentUrl));
            $localUrl = $this->_localImagesUrl . substr($lowPicUrl, strpos($lowPicUrl, $this->_baseContentUrl) + strlen($this->_baseContentUrl));

            // Check directory for local path
            $parentPath = dirname($localPath);
            if (!file_exists($parentPath)) {
                mkdir($parentPath, 0775, true);
            }

            if (!file_exists($localPath)) {
                $this->_downloader->downloadFile($lowPicUrl, $localPath);
            }
            $this->_product['low_pic_url'] = $localUrl;
        }

        // Save product thumb pic
        $thumbPicUrl = $this->_product['thumb_pic_url'];
        if ($thumbPicUrl) {
            $localPath = $this->_localImagesPath . substr($thumbPicUrl, strpos($thumbPicUrl, $this->_baseContentUrl) + strlen($this->_baseContentUrl));
            $localUrl = $this->_localImagesUrl . substr($thumbPicUrl, strpos($thumbPicUrl, $this->_baseContentUrl) + strlen($this->_baseContentUrl));

            // Check directory for local path
            $parentPath = dirname($localPath);
            if (!file_exists($parentPath)) {
                mkdir($parentPath, 0775, true);
            }

            if (!file_exists($localPath)) {
                $this->_downloader->downloadFile($thumbPicUrl, $localPath);
            }
            $this->_product['thumb_pic_url'] = $localUrl;
        }
    }

    /**
     * Process the start of an element in XML
     * @param obejct $parser
     * @param string $tag
     * @param array $attributes 
     */
    public function startElement($parser, $tag, $attributes)
    {
        if ('Category' == $tag) {
            // find ID of a category
            $categoryId = $this->_categoryModel->findIdByContentId($attributes['ID']);
            if ($categoryId) {
                $this->_product['category_id'] = $categoryId;
            }
        } elseif ('Product' == $tag) {
            if (!$this->_inProduct) {
                $this->_product['high_pic_url'] = $attributes['HighPic'];
                $this->_product['low_pic_url'] = $attributes['LowPic'];
                $this->_product['name'] = $attributes['Name'];
                $this->_product['mpn'] = $attributes['Prod_id'];
                $this->_product['quality'] = $attributes['Quality'];
                $this->_product['release_date'] = $attributes['ReleaseDate'];
                $this->_product['thumb_pic_url'] = $attributes['ThumbPic'];
                $this->_product['content_id'] = $this->_contentProductId;
            }
            $this->_inProduct++;
        } elseif ('ProductFeature' == $tag) {
            if ($attributes['Value'] != 'Icecat.biz') {
                $productFeature = array();
                $productFeature['localized'] = $attributes['Localized'];
                $productFeature['content_id'] = $attributes['ID'];
                $productFeature['value'] = $attributes['Value'];
                $productFeature['presentation_value'] = $attributes['Presentation_Value'];
                // find ID of a category feature
                $categoryFeatureId = $this->_categoryFeatureModel->findIdByContentId($attributes['CategoryFeature_ID']);
                if ($categoryFeatureId) {
                    $productFeature['category_feature_id'] = $categoryFeatureId;
                }
                array_push($this->_productFeatures, $productFeature);
            }
        } elseif ('ProductPicture' == $tag) {
            $productPicture = array();
            $productPicture['url'] = $attributes['Pic'];
            $productPicture['height'] = $attributes['PicHeight'];
            $productPicture['width'] = $attributes['PicWidth'];
            $productPicture['content_id'] = $attributes['ProductPicture_ID'];
            $productPicture['size'] = $attributes['Size'];
            $productPicture['thumb_url'] = $attributes['ThumbPic'];
            $productPicture['thumb_size'] = $attributes['ThumbSize'];
            array_push($this->_productPictures, $productPicture);
        } elseif ('ShortSummaryDescription' == $tag) {
            $this->_inShortSummaryDescription = 1;
        } elseif ('LongSummaryDescription' == $tag) {
            $this->_inLongSummaryDescription = 1;
        } elseif ('Supplier' == $tag) {
            // find ID of a manufacturer
            $manufacturerId = $this->_manufacturerModel->findIdByContentId($attributes['ID']);
            if ($manufacturerId) {
                $this->_product['manufacturer_id'] = $manufacturerId;
            }
        }
    }

    /**
     * Process the end of an element in XML
     * @param object $parser
     * @param string $tag 
     */
    public function endElement($parser, $tag)
    {
        if ('Product' == $tag) {
            $this->_inProduct--;
            if (!$this->_inProduct) {
                $this->_product['imported'] = new Zend_Db_Expr('NOW()');
                // find a product in the database
                $this->_product_id = $this->_productModel->findIdByContentId($this->_product['content_id']);
                if ($this->_product_id) {
                    // update the product
                    $this->_product['id'] = $this->_product_id;
                }
                $this->_saveProductImages();
                $this->_product_id = $this->_productModel->save($this->_product);
                // process product translation
                // find a product translation in the database
                $productTranslationId = $this->_productTranslationModel->findIdByProductAndLanguage($this->_product_id, $this->_languageId);
                if ($productTranslationId) {
                    // update the product translation
                    $this->_productTranslation['id'] = $productTranslationId;
                }
                $this->_productTranslation['language_id'] = $this->_languageId;
                $this->_productTranslation['product_id'] = $this->_product_id;
                $this->_productTranslationModel->save($this->_productTranslation);
                // process product features
                foreach ($this->_productFeatures as $productFeature) {

                    // process product feature translation
                    $productFeatureTranslation = array();
                    $productFeatureTranslation['language_id'] = $this->_languageId;
                    $productFeatureTranslation['presentation_value'] = $productFeature['presentation_value'];
                    unset($productFeature['presentation_value']);
                    // find a product feature in the database
                    $productFeatureId = $this->_productFeatureModel->findIdByContentId($productFeature['content_id']);
                    if ($productFeatureId) {
                        // update the product feature
                        $productFeature['id'] = $productFeatureId;
                        $this->_totalProductFeaturesUpdated++;
                    } else {
                        // insert the product feature
                        $this->_totalProductFeaturesInserted++;
                    }
                    $productFeature['product_id'] = $this->_product_id;
                    $productFeatureId = $this->_productFeatureModel->save($productFeature);
                    $this->_totalProductFeatures++;
                    // find a product feature translation in the database
                    $productFeatureTranslationId = $this->_productFeatureTranslationModel->findIdByProductFeatureAndLanguage($productFeatureId, $this->_languageId);
                    if ($productFeatureTranslationId) {
                        // update the product feature translation
                        $productFeatureTranslation['id'] = $productFeatureTranslationId;
                    }
                    $productFeatureTranslation['product_feature_id'] = $productFeatureId;
                    $this->_productFeatureTranslationModel->save($productFeatureTranslation);
                }
                // process product pictures
                foreach ($this->_productPictures as $productPicture) {

                    // find a product picture in the database
                    $productPictureId = $this->_productPictureModel->findIdByContentId($productPicture['content_id']);
                    if ($productPictureId) {
                        // update the product picture
                        $productPicture['id'] = $productPictureId;
                        $this->_totalProductPicturesUpdated++;
                    } else {
                        // insert the product picture
                        $this->_totalProductPicturesInserted++;
                    }
                    $productPicture['product_id'] = $this->_product_id;
                    $this->_productPictureModel->save($productPicture);
                    $this->_totalProductPictures++;
                }
            }
        } elseif ('ShortSummaryDescription' == $tag) {
            $this->_inShortSummaryDescription = 0;
        } elseif ('LongSummaryDescription' == $tag) {
            $this->_inLongSummaryDescription = 0;
        }
    }

    /**
     * Process characters in XML
     * @param object $parser
     * @param string $data 
     */
    public function characterData($parser, $data)
    {
        // characters in short summary description
        if ($this->_inShortSummaryDescription) {
            if (isset($this->_productTranslation['short_summary_description'])) {
                $this->_productTranslation['short_summary_description'] .= trim($data);
            } else {
                $this->_productTranslation['short_summary_description'] = trim($data);
            }
            // characters in long summary description
        } elseif ($this->_inLongSummaryDescription) {
            if (isset($this->_productTranslation['long_summary_description'])) {
                $this->_productTranslation['long_summary_description'].= trim($data);
            } else {
                $this->_productTranslation['long_summary_description'] = trim($data);
            }
        }
    }

    /**
     * Get the report about a parsing
     * @return string 
     */
    public function getReport()
    {
        $report = "$this->_totalProductFeatures product features in XML,";
        $report .= " $this->_totalProductFeaturesInserted inserted,";
        $report .= " $this->_totalProductFeaturesUpdated updated\n";
        $report .= "$this->_totalProductPictures product prictures in XML,";
        $report .= " $this->_totalProductPicturesInserted inserted,";
        $report .= " $this->_totalProductPicturesUpdated updated\n";
        return $report;
    }

    /**
     * Get ID of imported product
     * @return integer
     */
    public function getProductId()
    {
        return $this->_productId;
    }

}

